#include "ProDlgHead.h"

#include <QFontDatabase>
#include <QPainter>
#include <QSize>
#include <QPainterPath>
#include <QDebug>
#include <QString>
#include <QPoint>

#include "../IdRootMenu.h"
#include "../MenuIdConvert.h"
#include "../vhc/constview4color.h"

#include "../TViewDraw.h"

#include "../../rwidgets/MacroFunOfView.h"

#include "mcore/tools/setting/KeToolSettings.h"
#include "mcore/tools/EditWidget.h"





namespace kepen {
namespace core {

ProDlgHead::ProDlgHead(QWidget *parent,ProtactorToolView *parentContext,int width)
    : QWidget{parent},

    editContext(parentContext),
    isMouseLeftDown(false),
    isWindowDeactivate(false),
    m_nIdTouchedDown(MenuId_None),
    m_nIdMouseOver(MenuId_None)
{
    QSizePolicy sizePoFixed(QSizePolicy::Policy::Fixed, QSizePolicy::Policy::Fixed);
    sizePoFixed.setHorizontalStretch(0);
    sizePoFixed.setVerticalStretch(0);
    sizePoFixed.setHeightForWidth(false);

    setSizePolicy(sizePoFixed);
    setFixedSize(width,Height_CELL);

    int arr[]={  0x990002,
                 Label_PickVertexOrEged,
                 Pick_Target_Vertex,
                 0x990002,
                 Pick_Target_Edge,

                 0x99000f,


                 EditTool_Combox,
                 0x990012,
                 Option_EnSnapGraphic,
                 0x990002,
                 BarWinow_Minimize,
                 BarWinow_Close};

    const int count = sizeof(arr)/sizeof(arr[0]);
    const int sizeBuff = sizeof(arr);
    int nGridWidth,dif;
    int *idMenu = new int[count];
    cellWidthArr = new int[count];


    memcpy(idMenu,arr,sizeBuff);
    idMenuArray = idMenu;    
    m_nLengthMenu = count;

    nGridWidth = getGridWidth(count,idMenuArray, cellWidthArr);
    dif = width - nGridWidth;

    int idxLast2 = count- 1;
    int id = arr[idxLast2];
    while(false  == (IS_WhiteSpaceBar(id))){
        --idxLast2;
        id = arr[idxLast2];
    }
    cellWidthArr[idxLast2] += dif;

    setMouseTracking(true);
    QObject::installEventFilter(this);
}

ProDlgHead::~ProDlgHead()
{
    delete [] idMenuArray;
    delete [] cellWidthArr;

}

bool ProDlgHead::eventFilter(QObject *watched, QEvent *event)
{
    WindowDeactivate_EventFilter_Only()
}

void ProDlgHead::leaveEvent(QEvent *)
{
    m_nIdMouseOver = MenuId_None;
    repaint();
}


void ProDlgHead::mouseMoveEvent(QMouseEvent *event)
{
    if(false == isMouseLeftDown){
        QPointF point = event->position();
        int nIdMouseOver = m_nIdMouseOver;
        int comboBoxFlag = 0;
        m_nIdMouseOver = getIdOfTouched(point,comboBoxFlag);//mouseMoveEvent
        if(nIdMouseOver != m_nIdMouseOver || comboBoxFlagLast != comboBoxFlag)
        {
            comboBoxFlagLast = comboBoxFlag;
            repaint();
        }
    }
}


void ProDlgHead::mousePressEvent(QMouseEvent *event)
{
    Qt::MouseButton btn = event->button();
    if(Qt::MouseButton::LeftButton == btn)
    {
        QPointF point = event->position();
        int comboBoxFlag = 0;
        ptDown = point;
        isMouseLeftDown = true;
        m_nIdTouchedDown = getIdOfTouched(point,comboBoxFlag);//mousePressEvent
        comboBoxFlagLast = comboBoxFlag;
        m_nIdMouseOver = MenuId_None;
        // editContext->repaintToolBar();
        repaint();
    }
}


void ProDlgHead::mouseReleaseEvent(QMouseEvent *event)
{
    int idTouched = m_nIdTouchedDown;
    bool isIgnore =(MenuId_None == idTouched) ||((IS_WhiteSpaceBar(idTouched)));
    bool _isMouseLeftDown = isMouseLeftDown;
    m_nIdTouchedDown = MenuId_None;
    m_nIdMouseOver = MenuId_None;

    isMouseLeftDown = false;

    if(_isMouseLeftDown){
        Qt::MouseButton btn = event->button();
        if (Qt::MouseButton::LeftButton == btn)
        {
            QPointF pointUp = event->position();
            QPointF  ptUp = pointUp - ptDown;

            int retFlag =0;
            int x = ptUp.x(),y = ptUp.y();
            bool isClicked = x >-DisTorClicked && x < DisTorClicked && y >-DisTorClicked && y < DisTorClicked;
            bool isGo ,isRepaintRoot;




            if(false == isIgnore && isClicked)
            {
                bool isCombox = IS_ComboBox(idTouched);
                if(isCombox)
                {
                    QPoint point;
                    int comboBoxFlag = 0;
                    idTouched = getIdOfTouched(ptDown,comboBoxFlag);
                    getBtnPosition(idTouched,point);
                    QPoint pointGlobal =  mapToGlobal(point);
                    retFlag =  editContext->onComboxClicked(idTouched,comboBoxFlag,pointGlobal);

                }else
                {
                    retFlag =  editContext->onBtnClicked(idTouched);
                }

            }
            isGo = ViewClickFlag_Go == (ViewClickFlag_Go & retFlag);
            isRepaintRoot = ViewClickFlag_RepaintRoot == (ViewClickFlag_RepaintRoot & retFlag);

            if(false == isGo && false == isRepaintRoot){
                editContext->repaintToolBar();
            }

        }
    }

}


void ProDlgHead::paintEvent(QPaintEvent *)
{
    quint32 backColor = isWindowDeactivate?InDefault_Background:Default_Background;
    int widthWindow ,heightWidow;
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform | QPainter::TextAntialiasing |QPainter::VerticalSubpixelPositioning);

    QSize rectWin = this->size();
    widthWindow  = rectWin.width();
    heightWidow = rectWin.height();

    painter.fillRect(0,0,widthWindow ,heightWidow,QColor(QRgba64::fromArgb32(backColor)));

    onPaintButtons(&painter);

    QBrush brushBorder(Qt::darkGray,Qt::SolidPattern);
    QPen penBorder(brushBorder,1.0f, Qt::SolidLine);
    painter.setPen(penBorder);
    painter.setBrush(Qt::NoBrush);
    painter.drawRect(0,0,widthWindow ,heightWidow);
}


int ProDlgHead::getGridWidth(int length,const int *param, int *cellWidthArr){
    int widthTotal = 0;
    int  itemWidth, id;
    std::size_t i = 0, len = length;


    //
    for (; i < len; ++i) {
        id = param[i];
        if (IS_WhiteSpaceBar(id)) {
            itemWidth = WhiteSpace_M & id;

        }  else if (IS_ComboBox(id)) {
            if(EditTool_Combox ==id)
            {
                int nLabelWidth;
                QString strLabel = MenuIdConvert::GetLabelByID(Label_Update);
                QFontMetrics fontMetrics(editContext->fontLabel);
                QRect rect = fontMetrics.boundingRect(strLabel);
                nLabelWidth = rect.width();
                itemWidth = nLabelWidth + Width_ComboBox/*Width_CELL*/;
            }
            else
            {
                itemWidth = Width_ComboBox;
            }

        }else if(UpdateGPS_ByString == id
                   ||Edit_AddVertexOnLine == id
                   ||Edit_EraseVertex == id)
        {
            int nFontWidth;
            QString strLabel = MenuIdConvert::GetLabelByID(id);
            QFontMetrics fontMetrics(editContext->fontLabel);
            QRect rect = fontMetrics.boundingRect(strLabel);
            nFontWidth = rect.width();
            itemWidth = nFontWidth + Width_CELL;
        } else if (IS_LabelBar(id)) {

            int nFontWidth, pad = 8 ;
            QString strLabel = MenuIdConvert::GetLabelByID(id);
            QFontMetrics fontMetrics(editContext->fontLabel);
            QRect rect = fontMetrics.boundingRect(strLabel);
            nFontWidth = rect.width();
            itemWidth = nFontWidth + pad;
        } else if ( Pick_Target_Vertex == id ) {
            itemWidth = Width_CELL + 2 ;
        }else {
            itemWidth = Width_CELL;

        }

        widthTotal += itemWidth;
        cellWidthArr[i] = itemWidth;

    }

    return widthTotal;
}

int ProDlgHead::getIdOfTouched(const QPointF &point ,int &comboBoxFlag)
{
    int x0 = qRound(point.x());
    int nRet = MenuId_None;

    std::size_t i, numBtns = m_nLengthMenu;
    int left, right;
    int nCellWidth;
    // int _id;
    comboBoxFlag = 0;
    right =  0;

    for (i = 0; i < numBtns; ++i) {

        left = right;
        nCellWidth = cellWidthArr[i];
        right = left + nCellWidth;
        if (x0 >= left && x0 < right) {
            nRet = idMenuArray[i];
            if(IS_ComboBox(nRet))
            {
                int dd = right - RightClick_ComboBox;

                if(nCellWidth > Width_ComboBox )dd -= 3;

                if(x0 < dd)
                {
                    comboBoxFlag = Pos_ComboBox_Left;
                }
                else
                {
                    comboBoxFlag = Pos_ComboBox_Right;
                }

            }else
            {
                comboBoxFlag = 0;
            }
            break;
        }

    }

    return nRet;
}

void ProDlgHead::onPaintButtons(QPainter *painter)
{
    int childWidth = 0,childHeight = Height_CELL;
    int _nID_touchedDown = m_nIdTouchedDown;
    int nIdMouseOver = m_nIdMouseOver;
    bool isEnable=true,isChecked=true,isMouseOver,isTouchedDown,isDeAct = isWindowDeactivate;
    // bool isFocused = hasFocus();
    quint32 boolFlag;
    std::size_t i, numBtns = m_nLengthMenu;
    int left, right;
    int topOfLine = 0;

    int id,sizeTextIcon = TextSize_Icon_Tool;


    const int * cellWidthPtr = cellWidthArr;
    ProtactorParamData &param = editContext->segmentPicked->mProtaData;



    right =  0;
    for (i = 0; i < numBtns; ++i)
    {
        id = idMenuArray[i];
        left = right;
        childWidth = cellWidthPtr[i];
        right = left + childWidth;

        if (IS_WhiteSpaceBar(id))
            continue;

        if(Option_EnSnapGraphic == id)
        {
            kepen::core::MapObject *mapObj = editContext->mapSurface;
            kepen::core::EditWidget *ewPtr = mapObj->getEditWidgetSingleton();
            KeToolSettings *keSettingR2 = ewPtr->getMapToolSettings();

            isChecked = keSettingR2->m_EnSnapGraphic;

        }else
            isChecked = param.isCheckedBy(id);

        //if(PickMode_Line==id|| IdentifyMode_Point == id)isChecked = true;//test





        isMouseOver = nIdMouseOver == id;
        isTouchedDown = _nID_touchedDown == id;

        boolFlag = isChecked ? BoolFlagChecked : 0;

        if(isDeAct)boolFlag |= BoolFlagDeactivate;

        if(isEnable){
            boolFlag |= BoolFlagEnable;
            if(isMouseOver)boolFlag |= BoolFlagMouseOver;
            if(isTouchedDown)boolFlag |= BoolFlagTouched;
        }







        if(false == ((IS_WhiteSpaceBar(id)) ||  (IS_LabelBar(id)))){

            if(isChecked && false == isDeAct
                && false == isMouseOver
                && false == isTouchedDown)
            {
                QBrush _brushTogBtn(QColor(QRgba64::fromArgb32(Checked_Background)),Qt::SolidPattern);

                painter->fillRect(left, topOfLine, childWidth,childHeight,_brushTogBtn);
            }


            if (isEnable && isMouseOver
                && false == isTouchedDown){

                quint32 nBackColor =isDeAct?0xffffffffU: (isChecked ?  Checked_Background_Over : Background_BtnOver);
                QBrush brushBackOver(QColor(QRgba64::fromArgb32(nBackColor)),Qt::SolidPattern);


                painter->fillRect(left, topOfLine, childWidth,childHeight,brushBackOver);


            }

            if (isEnable && isTouchedDown){
                quint32 nBackColor = isChecked ?  Checked_Background2_Touched:Background_BtnDown;
                QBrush brushBackDown(QColor(QRgba64::fromArgb32(nBackColor)),Qt::SolidPattern);
                painter->fillRect(left, topOfLine, childWidth,childHeight,brushBackDown);

            }

        }


        if (IS_LabelBar(id)){
            if(nIdMouseOver == id && isDeAct){
                painter->fillRect(left, topOfLine, childWidth,childHeight,Qt::white);
            }
            DRAW_Text_Label(left,topOfLine,textSizeLabel,id)
        }else if (Pick_Target_Vertex == id) {
            TViewDraw::DrawShapePickPoint(painter,left, topOfLine, childWidth,childHeight, boolFlag);
        }else if (Pick_Target_Edge == id) {

            TViewDraw::DrawShapePickLine(painter,left, topOfLine, childWidth,childHeight, boolFlag);
        }else if(IS_ComboBox(id))
        {
            if(EditTool_Combox ==id)
            {
                int bb = childWidth;

                int id_display =  param.getComboBoxDisplay(id);
                int id4Label = Edit_AddVertexOnLine == id_display ? Label_Add:Label_Update;
                int textSize_icon = sizeTextIcon ;
                int _ntop = topOfLine ;
                int left_icon  ;
                int cx0, cy0,ntLeft,ntTop;

                int nLabelWidth,nIconWidth;
                quint32 textColor = isEnable ?(isChecked ?  Color_Font_ToolBar_checked:Color_Font_ToolBar) : Color_Font_Unable;

                QString strLabel = MenuIdConvert::GetLabelByID(id4Label);
                QFontMetrics fontMetrics(editContext->fontLabel);
                QRect rect = fontMetrics.boundingRect(strLabel);
                nLabelWidth = rect.width();



                cx0 = 3 + left + (nLabelWidth >> 1);
                cy0 = topOfLine + (childHeight >> 1);
                ntLeft = cx0 - 1000;
                ntTop = cy0 - 500;
                QRect rect4Text(ntLeft, ntTop, 2000, 1000);
                QBrush brushText(QColor(QRgba64::fromArgb32(textColor)),Qt::SolidPattern);
                QPen penText(brushText,1, Qt::SolidLine);
                painter->setFont(editContext->fontLabel);
                painter->setBrush(Qt::BrushStyle::NoBrush);
                painter->setPen(penText);
                painter->drawText(rect4Text,Qt::AlignCenter,strLabel);

                // DRAW_ICON_Font(left,_ntop,textSize,id_display)
                if(EditTool_LineExtrude == id_display)
                {
                    int cx0,cy0;

                    float  outLine []= Coords_EditTool_LineExtrude;
                    size_t length = sizeof(outLine)/sizeof(outLine[0]);
                    left_icon = left + nLabelWidth ;
                    nIconWidth = Width_ComboBox - WidthClick_ComboBox;
                    cx0 = left_icon + (nIconWidth >> 1);
                    cy0 = _ntop + (childHeight >> 1);

                    TViewDraw::DrawShapeCoords(painter,boolFlag,cx0,cy0,length,outLine);
                }else
                {


                    QFont &font_t = editContext->thirdFontIcon;


                    uint codeIconText = MenuIdConvert::GetIconTextByID(id_display);
                    QChar chTxtIcon(codeIconText);
                    QString szLabelIcon(chTxtIcon);
                    font_t.setPointSize(textSize_icon);

                    left_icon = left + nLabelWidth ;
                    nIconWidth = Width_ComboBox - WidthClick_ComboBox;
                    cx0 = left_icon + (nIconWidth >> 1);
                    cy0 = _ntop + (childHeight >> 1);
                    ntLeft = cx0 - 1000;
                    ntTop = cy0 - 500;
                    if(isDeAct)  textColor = Color_Text_Deactivate;

                    QRect rect4Text_icon(ntLeft, ntTop, 2000, 1000);
                    QBrush brushText_icon(QColor(QRgba64::fromArgb32(textColor)),Qt::SolidPattern);
                    QPen penText_icon(brushText_icon,1, Qt::SolidLine);
                    painter->setFont(font_t);
                    painter->setBrush(Qt::BrushStyle::NoBrush);
                    painter->setPen(penText_icon);
                    painter->drawText(rect4Text_icon,Qt::AlignCenter,szLabelIcon);


                    childWidth = bb;
                    ntLeft = left + childWidth - Width_ComboBoxFlag;
                    ntTop = topOfLine + childHeight - Height_ComboBoxFlag;
                    cx0 = ntLeft + (Width_ComboBoxFlag >> 1);
                    cy0 = ntTop + (Height_ComboBoxFlag >> 1);
                    TViewDraw::DrawComboxFlag(painter,cx0,cy0,boolFlag);
                }

            }
            else{
                int bb = childWidth;
                childWidth -= WidthClick_ComboBox;
                int id_display =  param.getComboBoxDisplay(id);
                if(EditTool_LineExtrude == id_display)
                {
                    int ntLeft,ntTop,cx0,cy0;

                    float  outLine []= Coords_EditTool_LineExtrude;
                    size_t length = sizeof(outLine)/sizeof(outLine[0]);
                    cx0 = left + (childWidth >> 1);
                    cy0 = topOfLine + ( childHeight>> 1) ;

                    TViewDraw::DrawShapeCoords(painter,boolFlag,cx0,cy0,length,outLine);

                    childWidth = bb;
                    ntLeft = left + childWidth - Width_ComboBoxFlag;
                    ntTop = topOfLine + childHeight - Height_ComboBoxFlag;
                    cx0 = ntLeft + (Width_ComboBoxFlag >> 1);
                    cy0 = ntTop + (Height_ComboBoxFlag >> 1);
                    TViewDraw::DrawComboxFlag(painter,cx0,cy0,boolFlag);
                }
                else
                {
                    int textSize = sizeTextIcon + 2;
                    int _ntop = topOfLine ;

                    DRAW_ICON_Font(left,_ntop,textSize,id_display)


                        childWidth = bb;
                    ntLeft = left + childWidth - Width_ComboBoxFlag;
                    ntTop = topOfLine + childHeight - Height_ComboBoxFlag;
                    cx0 = ntLeft + (Width_ComboBoxFlag >> 1);
                    cy0 = ntTop + (Height_ComboBoxFlag >> 1);
                    TViewDraw::DrawComboxFlag(painter,cx0,cy0,boolFlag);
                }

            }


        }else if(UpdateGPS_ByString == id
                   ||Edit_AddVertexOnLine == id
                   ||Edit_EraseVertex == id)
        {
            quint32 textColor = isDeAct && (nIdMouseOver != id)  ? Color_Text_Deactivate : Color_Font_ToolBar;
            QString strLabel = MenuIdConvert::GetLabelByID(id);
            int cx0, cy0,ntLeft,ntTop,widthLabel = childWidth -Width_CELL;
            cx0 = 4+left + (widthLabel >> 1);
            cy0 = topOfLine + (childHeight >> 1);
            ntLeft = cx0 - 1000;
            ntTop = cy0 - 500;
            QRect rect4Label(ntLeft, ntTop, 2000, 1000);
            QBrush brushLabel(QColor(QRgba64::fromArgb32(textColor)),Qt::SolidPattern);
            QPen penText(brushLabel,1, Qt::SolidLine);
            painter->setFont(editContext->fontLabel);
            painter->setBrush(Qt::BrushStyle::NoBrush);
            painter->setPen(penText);
            painter->drawText(rect4Label,Qt::AlignCenter,strLabel);

            ntLeft = left +widthLabel;



            QFont &font_t = editContext->thirdFontIcon;
            uint codeText = MenuIdConvert::GetIconTextByID(id);
            int _sizeTextIcon = (EditLayerOther == id)?(-2 +sizeTextIcon):(3 +sizeTextIcon);
            QChar chTxt(codeText);
            QString szIconLabel(chTxt);
            font_t.setPointSize(_sizeTextIcon);
            cx0 = ntLeft + (Width_CELL >> 1);
            cy0 = topOfLine + (childHeight >> 1);
            ntLeft = cx0 - 1000;
            ntTop = cy0 - 500;
            if(EditLayerOther == id)ntLeft += 2;
            QRect rect4Text(ntLeft, ntTop, 2000, 1000);

            painter->setFont(font_t);
            painter->setBrush(Qt::BrushStyle::NoBrush);
            painter->setPen(penText);
            painter->drawText(rect4Text,Qt::AlignCenter,szIconLabel);
        }else if (BarWinow_Minimize == id) {
            int cx0, cy0;
            int radius = 7;
            cx0 = left + (childWidth >> 1);
            cy0 = 5 + topOfLine + ( childHeight>> 1);
            TViewDraw::DrawBtnMinimize(painter,cx0,cy0,radius,boolFlag);

        }else if (BarWinow_Minimize == id) {
            int cx0, cy0;
            int radius = 6;
            cx0 = left + (childWidth >> 1);
            cy0 =  topOfLine + ( childHeight>> 1);
            TViewDraw::DrawBtnClose(painter,cx0,cy0,radius,boolFlag);

        }else if(Edit_AddVertexOnLine == id){
            int tn_sizeTextIcon = 4+sizeTextIcon;

            DRAW_ICON_Font(left,topOfLine,tn_sizeTextIcon,id)
        }
        else {

            DRAW_ICON_Font(left,topOfLine,sizeTextIcon,id)
        }


        if(isChecked)
            TViewDraw::DrawCheckedTriFlag(painter,left, topOfLine, childWidth,childHeight,boolFlag);

    }
}

void ProDlgHead::getBtnPosition(int id, QPoint &point)
{
    std::size_t i, numBtns = m_nLengthMenu;
    int left, right;
    int nCellWidth;
    right =  0;
    for (i = 0; i < numBtns; ++i) {

        left = right;

        if(id == idMenuArray[i])
        {
            nCellWidth = cellWidthArr[i];
            left = left + nCellWidth -WIDTH_DropCombox_CELL;
            point.setX(left);
            point.setY(Height_CELL);

            break;
        }

        nCellWidth = cellWidthArr[i];
        right = left + nCellWidth;
    }
}

}
}
